<?php

namespace App\App\Services;

use App\App\Services\Web\UserService;
use App\Models\ActivityInfo\ActivityInfo;
use App\Models\ActivityInfo\ActivityInfoService;
use App\Models\Goods\GoodsService;
use App\Models\Prize\Prize;
use App\Models\Prize\PrizeService as PrizeModelService;
use App\Models\PrizePayment\PrizePayment;
use App\Models\PrizePayment\PrizePaymentService;
use App\Models\PrizeRecord\PrizeRecord;
use App\Models\PrizeType\PrizeType;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Ramsey\Uuid\Uuid;
use EasyWeChat\Foundation\Application as WeChatApplication;


class PrizeService
{
    private $prizeService;
    private $prizePaymentService;
    private $prizeRecordService;
    private $userService;
    private $storageService;
    private $goodsService;
    private $activityInfoService;
    private $weChatApplication;

    public function __construct(PrizeModelService $prizeService, PrizePaymentService $paymentService, UserService $userService, StorageService $storageService, GoodsService $goodsService, ActivityInfoService $activityInfoService, WeChatApplication $weChatApplication)
    {
        $this->prizeService = $prizeService;
        $this->prizePaymentService = $paymentService;
        $this->userService = $userService;
        $this->goodsService = $goodsService;
        $this->activityInfoService = $activityInfoService;
        $this->weChatApplication = $weChatApplication;
        $this->storageService = $storageService;
    }

    /**
     * 构造查询条件
     * @param $requestData
     * @return array
     */
    public function prepareQueryConditiond($requestData)
    {
        $conditions = array();
        foreach ($requestData as $index => $condition) {
            if (empty($condition)) {
                unset($requestData[$index]);
                continue;
            }
            if ($index == 'name') {
                $conditions[] = array($index, 'like', '%' . $condition . '%');
            }else {
                if ($index == 'resource' && $condition == 2) {
                    $conditions[] = array('type_code', array(PrizeType::WECHAT, PrizeType::ALIPAY));
                } else {
                    $conditions[] = array($index, $condition);
                }
            }
        }
        $groupCode = $this->userService->getGroupCode();
        $conditions[] = array('group_code', $groupCode);
        return $conditions;
    }

    public function analyzeModifyInfo($prizeInfo)
    {
        if (in_array($prizeInfo['prize']['type_code'], array(PrizeType::COUPON, PrizeType::ENTITY))) {
            if (!empty($prizeInfo['prize']['background_image'])) {
                $fileArray = explode(':', $prizeInfo['prize']['background_image']);
                if (reset($fileArray) == 'http') {
                    $originalFile = $this->storageService->storeAsImage($prizeInfo['prize']['background_image']);
                    $prizeInfo['prize']['background_image'] = $originalFile['original'];
                }
            }
            $sponsorInfos = $prizeInfo['sponsor'];
            unset($prizeInfo['sponsor']);
            foreach ($sponsorInfos['name'] as $index => $item) {
                $prizeInfo['sponsor'][$index]['name'] = $item;
            }
            foreach ($sponsorInfos['percent'] as $index => $item) {
                $prizeInfo['sponsor'][$index]['percent'] = $item;
            }
            foreach ($sponsorInfos['logo'] as $index => $logoImage) {
                $fileArray = explode(':', $logoImage);
                if (reset($fileArray) == 'http') {
                    $originalFile = $this->storageService->storeAsImage($logoImage);
                    $prizeInfo['sponsor'][$index]['logo'] = $originalFile['original'];
                } else {
                    $prizeInfo['sponsor'][$index]['logo'] = $logoImage;
                }
            }
        } elseif ($prizeInfo['prize']['type_code'] == PrizeType::BUY) {
        } elseif (in_array($prizeInfo['prize']['type_code'], array(PrizeType::ALIPAY, PrizeType::WECHAT))) {
            $prizeInfo['prize']['name'] = date('Y-m-d H:i:s');
        }
        return $prizeInfo;
    }

    /**
     * 解析查询结果，获取奖品使用记录
     * @param $prizeInfos
     * @return array
     */
    public function analyzePrizeInfo($prizeInfos)
    {
        $showPrizeInfos = [];
        foreach ($prizeInfos['data'] as $prizeInfo) {
            $win = 0;
            if (!empty($prizeInfo['activity'])) {
                $activityIds = array_column($prizeInfo['activity'], 'id');
                $activityInfos = $this->activityInfoService->getActivity($activityIds);
                foreach ($activityInfos as $activityInfo) {
                    foreach ($activityInfo['activity_record'] as $activityRecord) {
                        if ($activityRecord['prize_id'] == $prizeInfo['id']) {
                            $win += $activityRecord['number'];
                        }
                    }
                }
            }
            $lockNumber = 0;
            $availableNumber = 0;
            $total = 0;
            if (!empty($prizeInfo['prize_record'])) {
                $prizeRecordSummary = array_column($prizeInfo['prize_record'], 'summary', 'updated_at');
                ksort($prizeRecordSummary);
                $availableNumber = end($prizeRecordSummary);
                foreach ($prizeInfo['prize_record'] as $prizeRecord) {
                    if (!in_array($prizeRecord['operate'],[PrizeRecord::DELIVERY,PrizeRecord::RECYCLE])
                        && empty($prizeRecord['activity_id'])) {
                        $total += $prizeRecord['number'];
                    }
                    if ($prizeRecord['operate'] == PrizeRecord::DELIVERY && empty($prizeRecord['activity_id'])) {
                        $total -= $prizeRecord['number'];
                    }
                    if ($prizeRecord['operate'] == PrizeRecord::DELIVERY && $prizeRecord['activity_id']) {
                        $lockNumber += $prizeRecord['number'];
                    }
                    if (in_array($prizeRecord['operate'], [PrizeRecord::ENTEY,PrizeRecord::RECYCLE])
                        && $prizeRecord['activity_id']) {
                        $lockNumber -= $prizeRecord['number'];
                    }
                }
            }
            if (in_array($prizeInfo['type_code'], array(PrizeType::ALIPAY, PrizeType::WECHAT))) {
                $total = number_format($total, 2);
                $lockNumber = number_format($lockNumber, 2);
                $win = number_format($win, 2);
                $availableNumber = number_format($availableNumber, 2);
            }
            $resourceTypes = Prize::RESOURCE_TYPES;
            $payStatus = '';
            $orderId = '';
            if (!empty($prizeInfo['prize_payment'])) {
                $payStatus = $prizeInfo['prize_payment']['status'];
                $orderId = $prizeInfo['prize_payment']['order_id'];
            }
            $showPrizeInfos[$prizeInfo['id']]['id'] = $prizeInfo['id'];
            $showPrizeInfos[$prizeInfo['id']]['name'] = $prizeInfo['name'];
            $showPrizeInfos[$prizeInfo['id']]['resource'] = $resourceTypes[$prizeInfo['resource']];
            $showPrizeInfos[$prizeInfo['id']]['expiredStart'] = $prizeInfo['expired_start'];
            $showPrizeInfos[$prizeInfo['id']]['expiredEnd'] = $prizeInfo['expired_end'];
            $showPrizeInfos[$prizeInfo['id']]['typeName'] = $prizeInfo['prize_type']['name'];
            $showPrizeInfos[$prizeInfo['id']]['typeCode'] = $prizeInfo['type_code'];
            $showPrizeInfos[$prizeInfo['id']]['stockNumber'] = $total;
            $showPrizeInfos[$prizeInfo['id']]['lockNumber'] = $lockNumber;
            $showPrizeInfos[$prizeInfo['id']]['recordNumber'] = $win;
            $showPrizeInfos[$prizeInfo['id']]['isValid'] = $prizeInfo['is_valid'];
            $showPrizeInfos[$prizeInfo['id']]['orderId'] = $orderId;
            $showPrizeInfos[$prizeInfo['id']]['payStatus'] = $payStatus;
            $showPrizeInfos[$prizeInfo['id']]['availableNumber'] = $availableNumber;
        }
        return $showPrizeInfos;
    }

    /**
     * 解析奖品使用记录
     * @param $prizeInfo
     * @return array
     */
    public function analyzePrizeRecord($prizeInfo)
    {
        $prizeName = $prizeInfo['name'];
        $typeCode = $prizeInfo['type_code'];
        $showPrizeRecords = array();
        if ($prizeInfo['type_code'] == PrizeType::ENTITY) {
            $operateSetting = PrizeRecord::ENTITY_OPERATES;
        } else {
            $operateSetting = PrizeRecord::MONEY_OPERATES;
        }
        $createTime = array_column($prizeInfo['prize_record'], 'created_at');
        array_multisort($createTime, SORT_DESC, $prizeInfo['prize_record']);
        foreach ($prizeInfo['prize_record'] as $prizeRecord) {
            if ($prizeRecord['activity_id']) {
                Log::info($prizeRecord);
                if (!isset($activityPrizes[$prizeRecord['activity_id']])) {
                    $activityPrizes[$prizeRecord['activity_id']] = 0;
                }
                $activityIds[] = $prizeRecord['activity_id'];
                //deliver释放 entry占用
                if ($prizeRecord['operate'] == PrizeRecord::ENTEY) {
                    $activityPrizes[$prizeRecord['activity_id']] -= $prizeRecord['number'];
                } elseif ($prizeRecord['operate'] == PrizeRecord::DELIVERY) {
                    $activityPrizes[$prizeRecord['activity_id']] += $prizeRecord['number'];
                }
            }
            if (in_array($typeCode, array(PrizeType::WECHAT, PrizeType::ALIPAY))) {
                $prizeRecord['number'] = number_format($prizeRecord['number'], 2);
                $prizeRecord['summary'] = number_format($prizeRecord['summary'], 2);
            }
            $showPrizeRecords[] = array(
                'date' => $prizeRecord['created_at'],
                'operate' => @$operateSetting[$prizeRecord['operate']] ?: $prizeRecord['operate'],
                'number' => $prizeRecord['number'],
                'summary' => $prizeRecord['summary']
            );
        }
        $prizeActivities = array();
        if (!empty($activityIds)) {
            $activityInfos = $this->activityInfoService->getActivity($activityIds);
            $createTime = array_column($activityInfos, 'created_at');
            array_multisort($createTime, SORT_DESC, $activityInfos);
            foreach ($activityInfos as $activityInfo) {
                $win = 0;
                $exchange = 0;
                $notExchange = 0;
                $createTime = array_column($activityInfo['activity_record'], 'created_at');
                array_multisort($createTime, $activityInfo['activity_record']);
                foreach ($activityInfo['activity_record'] as $activityRecord) {
                    if ($activityRecord['prize_id'] == $prizeInfo['id']) {
                        $win += $activityRecord['number'];
                        if ($activityRecord['is_exchange'] == ActivityInfo::IS_EXCHANGE_NO) {
                            $notExchange += $activityRecord['number'];
                        } else {
                            $exchange += $activityRecord['number'];
                        }
                    }
                }
                if( !isset($activityPrizes[$activityInfo['id']]) ) {
                    $activityPrizes[$activityInfo['id']] = 0;
                }
                $remain = $activityPrizes[$activityInfo['id']] - $win;
                if (in_array($typeCode, array(PrizeType::ALIPAY, PrizeType::WECHAT))) {
                    $win = number_format($win, 2);
                    $exchange = number_format($exchange, 2);
                    $notExchange = number_format($notExchange, 2);
                    $remain = number_format($remain, 2);
                } else {
                    $win = number_format($win, 0);
                    $exchange = number_format($exchange, 0);
                    $notExchange = number_format($notExchange, 0);
                    $remain = number_format($remain, 0);
                }
                $prizeActivities[] = array(
                    'activityName' => $activityInfo['name'],
                    'number' => $activityPrizes[$activityInfo['id']],
                    'win' => $win,
                    'exchange' => $exchange,
                    'notExchange' => $notExchange,
                    'remain' => $remain
                );
            }
        }
        return ['prizeName' => $prizeName, 'typeCode' => $typeCode, 'showPrizeRecords' => $showPrizeRecords, 'prizeActivities' => $prizeActivities];
    }

    /**
     * 保存奖品记录到数据库
     * @param $prizeInfo
     * @return mixed
     */
    public function analyzeCreateInfo($prizeInfo)
    {
        $prizeInfo['prize']['is_valid'] = Prize::IS_VALID_NO;
        if (in_array($prizeInfo['prize']['type_code'], array(PrizeType::COUPON, PrizeType::ENTITY))) {
            if (!empty($prizeInfo['prize']['voucher_link'])) {
                $originalFile = $this->storageService->storeAsImage($prizeInfo['prize']['voucher_link']);
                $prizeInfo['prize']['voucher_link'] = $originalFile['original'];
            }
            if (!empty($prizeInfo['prize']['background_image'])) {
                $originalFile = $this->storageService->storeAsImage($prizeInfo['prize']['background_image']);
                $prizeInfo['prize']['background_image'] = $originalFile['original'];
            }
            $prizeInfo['prize']['is_valid'] = Prize::IS_VALID_YES;
        } elseif ($prizeInfo['prize']['type_code'] == PrizeType::BUY) {
        } elseif ($prizeInfo['prize']['type_code'] == PrizeType::WECHAT) {
            $prizeInfo['prize']['stock_number'] = $prizeInfo['prize']['stock_number'];
        } elseif ($prizeInfo['prize']['type_code'] == PrizeType::ALIPAY) {
            $prizeInfo['prize']['stock_number'] = $prizeInfo['prize']['stock_number'];
        }
        $userInfo = $this->userService->getLoginUser();
        $prizeInfo['prize']['user_id'] = $userInfo['id'];
        $sponsorInfos = $prizeInfo['sponsor'];
        unset($prizeInfo['sponsor']);
        foreach ($sponsorInfos['name'] as $index => $item) {
            $prizeInfo['sponsor'][$index]['name'] = $item;
        }
        foreach ($sponsorInfos['percent'] as $index => $item) {
            $prizeInfo['sponsor'][$index]['percent'] = $item;
        }
        foreach ($sponsorInfos['logo'] as $index => $logoImage) {
            if ($logoImage) {
                $originalFile = $this->storageService->storeAsImage($logoImage);
                $prizeInfo['sponsor'][$index]['logo'] = $originalFile['original'];
            } else {
                $prizeInfo['sponsor'][$index]['logo'] = '';
            }
        }
        $prizeInfo['prizeRecord'] = array(
            'number' => $prizeInfo['prize']['stock_number'],
            'summary' => $prizeInfo['prize']['stock_number'],
            'operate' => PrizeRecord::CREATE
        );
        return $prizeInfo;
    }

    /**
     * 保存订单信息到缓存
     * @param $prizeInfo
     * @return array
     */
    public function createOrder($prizeInfo)
    {
        switch ($prizeInfo['prize']['type_code']) {
            case PrizeType::WECHAT:
                $orderIdPrefix = 'wx';
                $orderName = $prizeInfo['prize']['name'];
                $goodsName = $prizeInfo['prize']['name'];
                $goodsPrice = $prizeInfo['prize']['stock_number'];
                $goodsNumber = 1;
                $description = '';
                break;
            case PrizeType::ALIPAY:
                $orderIdPrefix = 'al';
                $orderName = $prizeInfo['prize']['name'];
                $goodsName = $prizeInfo['prize']['name'];
                $goodsPrice = $prizeInfo['prize']['stock_number'];
                $goodsNumber = 1;
                $description = '';
                break;
            case PrizeType::BUY:
                $orderIdPrefix = 'gm';
                $goodsInfo = $this->goodsService->getById($prizeInfo['prize']['goods_id']);
                $orderName = $goodsInfo['name'];
                $goodsName = $goodsInfo['name'];
                $goodsPrice = $goodsInfo['price'];
                $goodsNumber = $prizeInfo['stock_number'];
                $description = '';
                break;
        }
        $mTime = microtime(true) * 10000;
        $merchantId = $this->weChatApplication->merchant->merchant_id;
        $orderID = $orderIdPrefix . $merchantId . date('YmdisH') . substr($mTime, 10);
        $prizeInfo['order'] = array(
            'order_id' => $orderID,
            'user_id' => $prizeInfo['prize']['user_id'],
            'order_name' => $orderName,
            'goods_name' => $goodsName,
            'prize_id' => $prizeInfo['prize']['id'],
            'price' => $goodsPrice,
            'number' => $goodsNumber,
            'description' => $description,
            'created_at' => date('Y-m-d H:i:s'),
            'status' => PrizePayment::PAY_UNPAID
        );
        $this->prizePaymentService->create($prizeInfo['order']);
        return $prizeInfo;
    }
}
